1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect.testing.testers;
18
19 import static com.google.common.collect.testing.features.CollectionSize.ZERO;
20 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
21 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
22 import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
23 import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
24
25 import com.google.common.annotations.GwtCompatible;
26 import com.google.common.annotations.GwtIncompatible;
27 import com.google.common.collect.testing.AbstractMapTester;
28 import com.google.common.collect.testing.Helpers;
29 import com.google.common.collect.testing.features.CollectionSize;
30 import com.google.common.collect.testing.features.MapFeature;
31
32 import java.lang.reflect.Method;
33 import java.util.ConcurrentModificationException;
34 import java.util.Iterator;
35 import java.util.Map;
36 import java.util.Map.Entry;
37
38
39
40
41
42
43
44
45
46 @SuppressWarnings("unchecked")
47 @GwtCompatible(emulated = true)
48 public class MapPutTester<K, V> extends AbstractMapTester<K, V> {
49 private Entry<K, V> nullKeyEntry;
50 private Entry<K, V> nullValueEntry;
51 private Entry<K, V> nullKeyValueEntry;
52 private Entry<K, V> presentKeyNullValueEntry;
53
54 @Override public void setUp() throws Exception {
55 super.setUp();
56 nullKeyEntry = entry(null, samples.e3.getValue());
57 nullValueEntry = entry(samples.e3.getKey(), null);
58 nullKeyValueEntry = entry(null, null);
59 presentKeyNullValueEntry = entry(samples.e0.getKey(), null);
60 }
61
62 @MapFeature.Require(SUPPORTS_PUT)
63 public void testPut_supportedNotPresent() {
64 assertNull("put(notPresent, value) should return null", put(samples.e3));
65 expectAdded(samples.e3);
66 }
67
68 @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
69 @CollectionSize.Require(absent = ZERO)
70 public void testPutAbsentConcurrentWithEntrySetIteration() {
71 try {
72 Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
73 put(samples.e3);
74 iterator.next();
75 fail("Expected ConcurrentModificationException");
76 } catch (ConcurrentModificationException expected) {
77
78 }
79 }
80
81 @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
82 @CollectionSize.Require(absent = ZERO)
83 public void testPutAbsentConcurrentWithKeySetIteration() {
84 try {
85 Iterator<K> iterator = getMap().keySet().iterator();
86 put(samples.e3);
87 iterator.next();
88 fail("Expected ConcurrentModificationException");
89 } catch (ConcurrentModificationException expected) {
90
91 }
92 }
93
94 @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
95 @CollectionSize.Require(absent = ZERO)
96 public void testPutAbsentConcurrentWithValueIteration() {
97 try {
98 Iterator<V> iterator = getMap().values().iterator();
99 put(samples.e3);
100 iterator.next();
101 fail("Expected ConcurrentModificationException");
102 } catch (ConcurrentModificationException expected) {
103
104 }
105 }
106
107 @MapFeature.Require(absent = SUPPORTS_PUT)
108 public void testPut_unsupportedNotPresent() {
109 try {
110 put(samples.e3);
111 fail("put(notPresent, value) should throw");
112 } catch (UnsupportedOperationException expected) {
113 }
114 expectUnchanged();
115 expectMissing(samples.e3);
116 }
117
118 @MapFeature.Require(absent = SUPPORTS_PUT)
119 @CollectionSize.Require(absent = ZERO)
120 public void testPut_unsupportedPresentExistingValue() {
121 try {
122 assertEquals("put(present, existingValue) should return present or throw",
123 samples.e0.getValue(), put(samples.e0));
124 } catch (UnsupportedOperationException tolerated) {
125 }
126 expectUnchanged();
127 }
128
129 @MapFeature.Require(absent = SUPPORTS_PUT)
130 @CollectionSize.Require(absent = ZERO)
131 public void testPut_unsupportedPresentDifferentValue() {
132 try {
133 getMap().put(samples.e0.getKey(), samples.e3.getValue());
134 fail("put(present, differentValue) should throw");
135 } catch (UnsupportedOperationException expected) {
136 }
137 expectUnchanged();
138 }
139
140 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
141 public void testPut_nullKeySupportedNotPresent() {
142 assertNull("put(null, value) should return null", put(nullKeyEntry));
143 expectAdded(nullKeyEntry);
144 }
145
146 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
147 @CollectionSize.Require(absent = ZERO)
148 public void testPut_nullKeySupportedPresent() {
149 Entry<K, V> newEntry = entry(null, samples.e3.getValue());
150 initMapWithNullKey();
151 assertEquals("put(present, value) should return the associated value",
152 getValueForNullKey(), put(newEntry));
153
154 Entry<K, V>[] expected = createArrayWithNullKey();
155 expected[getNullLocation()] = newEntry;
156 expectContents(expected);
157 }
158
159 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_KEYS)
160 public void testPut_nullKeyUnsupported() {
161 try {
162 put(nullKeyEntry);
163 fail("put(null, value) should throw");
164 } catch (NullPointerException expected) {
165 }
166 expectUnchanged();
167 expectNullKeyMissingWhenNullKeysUnsupported(
168 "Should not contain null key after unsupported put(null, value)");
169 }
170
171 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
172 public void testPut_nullValueSupported() {
173 assertNull("put(key, null) should return null", put(nullValueEntry));
174 expectAdded(nullValueEntry);
175 }
176
177 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
178 public void testPut_nullValueUnsupported() {
179 try {
180 put(nullValueEntry);
181 fail("put(key, null) should throw");
182 } catch (NullPointerException expected) {
183 }
184 expectUnchanged();
185 expectNullValueMissingWhenNullValuesUnsupported(
186 "Should not contain null value after unsupported put(key, null)");
187 }
188
189 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
190 @CollectionSize.Require(absent = ZERO)
191 public void testPut_replaceWithNullValueSupported() {
192 assertEquals("put(present, null) should return the associated value",
193 samples.e0.getValue(), put(presentKeyNullValueEntry));
194 expectReplacement(presentKeyNullValueEntry);
195 }
196
197 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
198 @CollectionSize.Require(absent = ZERO)
199 public void testPut_replaceWithNullValueUnsupported() {
200 try {
201 put(presentKeyNullValueEntry);
202 fail("put(present, null) should throw");
203 } catch (NullPointerException expected) {
204 }
205 expectUnchanged();
206 expectNullValueMissingWhenNullValuesUnsupported(
207 "Should not contain null after unsupported put(present, null)");
208 }
209
210 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
211 @CollectionSize.Require(absent = ZERO)
212 public void testPut_replaceNullValueWithNullSupported() {
213 initMapWithNullValue();
214 assertNull("put(present, null) should return the associated value (null)",
215 getMap().put(getKeyForNullValue(), null));
216 expectContents(createArrayWithNullValue());
217 }
218
219 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
220 @CollectionSize.Require(absent = ZERO)
221 public void testPut_replaceNullValueWithNonNullSupported() {
222 Entry<K, V> newEntry = entry(getKeyForNullValue(), samples.e3.getValue());
223 initMapWithNullValue();
224 assertNull("put(present, value) should return the associated value (null)",
225 put(newEntry));
226
227 Entry<K, V>[] expected = createArrayWithNullValue();
228 expected[getNullLocation()] = newEntry;
229 expectContents(expected);
230 }
231
232 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS, ALLOWS_NULL_VALUES})
233 public void testPut_nullKeyAndValueSupported() {
234 assertNull("put(null, null) should return null", put(nullKeyValueEntry));
235 expectAdded(nullKeyValueEntry);
236 }
237
238 private V put(Map.Entry<K, V> entry) {
239 return getMap().put(entry.getKey(), entry.getValue());
240 }
241
242
243
244
245
246
247
248
249
250 @GwtIncompatible("reflection")
251 public static Method getPutNullKeyUnsupportedMethod() {
252 return Helpers.getMethod(MapPutTester.class, "testPut_nullKeyUnsupported");
253 }
254 }